package com.caipu.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.caipu.dto.DishDetailDTO;
import com.caipu.dto.DishSearchDTO;
import com.caipu.entity.*;
import com.caipu.mapper.*;
import com.caipu.service.DishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {
    
    @Autowired
    private CategoryMapper categoryMapper;
    
    @Autowired
    private TagMapper tagMapper;
    
    @Autowired
    private DishTagMapper dishTagMapper;
    
    @Override
    public Page<DishDetailDTO> searchDishes(DishSearchDTO searchDTO) {
        Page<Dish> page = new Page<>(searchDTO.getPage(), searchDTO.getSize());
        
        QueryWrapper<Dish> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("deleted", 0);
        
        if (searchDTO.getCategoryId() != null) {
            queryWrapper.eq("category_id", searchDTO.getCategoryId());
        }
        
        if (StringUtils.hasText(searchDTO.getKeyword())) {
            queryWrapper.like("name", searchDTO.getKeyword());
        }
        
        // 如果有标签筛选，需要特殊处理
        if (searchDTO.getTagIds() != null && !searchDTO.getTagIds().isEmpty()) {
            List<Long> dishIds = dishTagMapper.selectList(
                new QueryWrapper<DishTag>().in("tag_id", searchDTO.getTagIds())
            ).stream().map(DishTag::getDishId).distinct().collect(Collectors.toList());
            
            if (!dishIds.isEmpty()) {
                queryWrapper.in("id", dishIds);
            } else {
                // 没有符合条件的菜品
                return new Page<>(searchDTO.getPage(), searchDTO.getSize());
            }
        }
        
        Page<Dish> dishPage = this.page(page, queryWrapper);
        
        // 转换为DTO
        Page<DishDetailDTO> resultPage = new Page<>();
        BeanUtils.copyProperties(dishPage, resultPage);
        
        List<DishDetailDTO> dtoList = dishPage.getRecords().stream()
            .map(this::convertToDetailDTO)
            .collect(Collectors.toList());
        
        resultPage.setRecords(dtoList);
        return resultPage;
    }
    
    @Override
    public DishDetailDTO getDishDetail(Long id) {
        Dish dish = this.getById(id);
        if (dish == null) {
            return null;
        }
        return convertToDetailDTO(dish);
    }
    
    @Override
    public DishDetailDTO randomSelectDish(DishSearchDTO searchDTO) {
        // 获取符合条件的所有菜品
        searchDTO.setPage(1);
        searchDTO.setSize(Integer.MAX_VALUE);
        Page<DishDetailDTO> dishPage = searchDishes(searchDTO);
        
        List<DishDetailDTO> dishes = dishPage.getRecords();
        if (dishes.isEmpty()) {
            return null;
        }
        
        // 随机选择一个
        Random random = new Random();
        int index = random.nextInt(dishes.size());
        return dishes.get(index);
    }
    
    @Override
    @Transactional
    public void addDishTags(Long dishId, List<Long> tagIds) {
        if (tagIds == null || tagIds.isEmpty()) {
            return;
        }
        
        // 删除已存在的关联
        dishTagMapper.delete(new QueryWrapper<DishTag>().eq("dish_id", dishId).in("tag_id", tagIds));
        
        // 添加新的关联
        List<DishTag> dishTags = tagIds.stream().map(tagId -> {
            DishTag dishTag = new DishTag();
            dishTag.setDishId(dishId);
            dishTag.setTagId(tagId);
            dishTag.setCreateTime(LocalDateTime.now());
            return dishTag;
        }).collect(Collectors.toList());
        
        dishTags.forEach(dishTagMapper::insert);
    }
    
    @Override
    @Transactional
    public void removeDishTags(Long dishId, List<Long> tagIds) {
        if (tagIds == null || tagIds.isEmpty()) {
            return;
        }
        
        dishTagMapper.delete(new QueryWrapper<DishTag>()
            .eq("dish_id", dishId)
            .in("tag_id", tagIds));
    }
    
    private DishDetailDTO convertToDetailDTO(Dish dish) {
        DishDetailDTO dto = new DishDetailDTO();
        BeanUtils.copyProperties(dish, dto);
        
        // 解析详情图片JSON
        if (StringUtils.hasText(dish.getDetailImages())) {
            try {
                List<String> images = JSON.parseArray(dish.getDetailImages(), String.class);
                dto.setDetailImages(images);
            } catch (Exception e) {
                dto.setDetailImages(new ArrayList<>());
            }
        } else {
            dto.setDetailImages(new ArrayList<>());
        }
        
        // 获取分类信息
        if (dish.getCategoryId() != null) {
            Category category = categoryMapper.selectById(dish.getCategoryId());
            dto.setCategory(category);
        }
        
        // 获取标签信息
        List<Long> tagIds = dishTagMapper.getTagIdsByDishId(dish.getId());
        if (!tagIds.isEmpty()) {
            List<Tag> tags = tagMapper.selectBatchIds(tagIds);
            dto.setTags(tags);
        } else {
            dto.setTags(new ArrayList<>());
        }
        
        return dto;
    }
    
    @Override
    public Page<DishDetailDTO> getDishesByIds(List<Long> dishIds, int page, int size) {
        if (dishIds == null || dishIds.isEmpty()) {
            return new Page<>(page, size);
        }
        
        Page<Dish> dishPage = new Page<>(page, size);
        QueryWrapper<Dish> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", dishIds);
        queryWrapper.eq("deleted", 0);
        queryWrapper.orderByDesc("create_time");
        
        Page<Dish> result = this.page(dishPage, queryWrapper);
        
        Page<DishDetailDTO> dtoPage = new Page<>(page, size);
        dtoPage.setTotal(result.getTotal());
        dtoPage.setPages(result.getPages());
        
        List<DishDetailDTO> dtoList = result.getRecords().stream()
                .map(this::convertToDetailDTO)
                .collect(Collectors.toList());
        dtoPage.setRecords(dtoList);
        
        return dtoPage;
    }
    
    @Override
    public List<DishDetailDTO> getRecommendedDishes() {
        // 查询收藏数最高的50个菜品
        String sql = "SELECT d.* FROM dish d " +
                    "LEFT JOIN (SELECT dish_id, COUNT(*) as favorite_count FROM user_favorite GROUP BY dish_id) f " +
                    "ON d.id = f.dish_id " +
                    "WHERE d.deleted = 0 " +
                    "ORDER BY IFNULL(f.favorite_count, 0) DESC, d.id ASC " +
                    "LIMIT 50";
        
        List<Dish> topDishes = dishMapper.selectByCustomSql(sql);
        
        if (topDishes.isEmpty()) {
            // 如果没有收藏数据，则随机选择50个菜品
            QueryWrapper<Dish> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("deleted", 0);
            queryWrapper.orderByAsc("RAND()");
            queryWrapper.last("LIMIT 50");
            topDishes = this.list(queryWrapper);
        }
        
        if (topDishes.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 从这50个菜品中随机选择10个
        Collections.shuffle(topDishes);
        List<Dish> selectedDishes = topDishes.stream()
                .limit(10)
                .collect(Collectors.toList());
        
        return selectedDishes.stream()
                .map(this::convertToDetailDTO)
                .collect(Collectors.toList());
    }
    
    @Override
    public List<DishDetailDTO> getRandomDishes(List<Long> categoryIds, List<Long> tagIds, List<Long> dishIds) {
        // 如果指定了具体菜品ID，直接返回这些菜品
        if (dishIds != null && !dishIds.isEmpty()) {
            List<Dish> dishes = this.listByIds(dishIds);
            return dishes.stream()
                    .filter(dish -> dish.getDeleted() == 0)
                    .map(this::convertToDetailDTO)
                    .collect(Collectors.toList());
        }
        
        // 根据分类和标签筛选菜品
        QueryWrapper<Dish> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("deleted", 0);
        
        if (categoryIds != null && !categoryIds.isEmpty()) {
            queryWrapper.in("category_id", categoryIds);
        }
        
        // 如果有标签筛选，需要特殊处理
        if (tagIds != null && !tagIds.isEmpty()) {
            List<Long> filteredDishIds = dishTagMapper.selectList(
                new QueryWrapper<DishTag>().in("tag_id", tagIds)
            ).stream().map(DishTag::getDishId).distinct().collect(Collectors.toList());
            
            if (!filteredDishIds.isEmpty()) {
                queryWrapper.in("id", filteredDishIds);
            } else {
                // 没有符合条件的菜品
                return new ArrayList<>();
            }
        }
        
        queryWrapper.orderByAsc("RAND()");
        queryWrapper.last("LIMIT 20");
        
        List<Dish> dishes = this.list(queryWrapper);
        return dishes.stream()
                .map(this::convertToDetailDTO)
                .collect(Collectors.toList());
    }
}